#include "EngineStart.h"
#include "tim_hw.h"
#include "debug_prt.h"
#include "CANProcess.h"
#include "CarMonitor.h"
#include "IO_Ctrl_hw.h"
#include "l610.h"

#if def_EngineStart

uint8_t  getCarReady(void);
uint8_t  getCarFootBrake(void);
uint8_t  getCarHandBrake(void);
uint8_t getGearsNOrP(void);
uint8_t getRelayCurSta(void);
uint8_t getCurEngine(void);
uint16_t getCurSpeed(void);

uint16_t Rotate_speed = 0;	//以后要求油车采集发动机转速


EngineStart_DataTypeDef	tagEngS;


void initEngS_Var(void)
{
	memset(&tagEngS, 0, sizeof(EngineStart_DataTypeDef));
}

/*
返回一键启动按键状态，放在位置信息的敬告微第0位
*/
uint8_t getCurEngStartKeySta(void)
{
	return tagEngS.keySta;
}

/*
当检测到有按键时才执行动作，其它时间不执行动作
按键检测需要防抖
*/
void deal_engine_start(void)
{
	uint8_t curRelaySta;
	uint8_t curEngineSta;
	uint16_t curSpeed;	//单位百米
	uint8_t curBrake;
	uint8_t curReady;
	uint8_t N_P;
	uint8_t curHandBrake;

	uint8_t ServerEngineCtrl = 0;	//02要求熄火，01要求点火
	#if def_OffDlySec
	static u32 offDectecSta = 0;
	static u32 offDlyCntOld = 0;
	static u32 offDlyCnt = 0;	//熊总要求超过3秒熄火才能启动
	#endif


	//外部按键检测
	detect_engine_start_keyPress();


	//通电返回1，断电返回0
	ServerEngineCtrl = tagEngS.startp_ctl;	//后台命令
	tagEngS.startp_ctl = 0;
	

	//后台命令和按钮要互斥
	
	//当检测到按键操作时，不允许执行后台命令
	if ((tagEngS.StartEngSta == 0x00) &&
		(tagEngS.keySta == 0x01))
	{
		if (ServerEngineCtrl != 0)
		{
			tagEngS.ErrorCode = 0x20;
			
		}
		ServerEngineCtrl = 0;
	}
	
	//当正在执行后台或按钮命令时，不允许二次执行后台命令
	if (tagEngS.StartEngSta != 0x00)
	{
		if (ServerEngineCtrl != 0)
		{
			tagEngS.ErrorCode = 0x40;
			
		}
		ServerEngineCtrl = 0;
	}
	
	#if def_EngineStartByServerCtrlfootbrakerelay
	if(ServerEngineCtrl == 0x21)
	{
		lock_IO_contrl(1);
	}
	#endif	
	
	curRelaySta = getRelayCurSta();	//断电继电器状态
	curEngineSta = getCurEngine();//1点火；0熄火,指ACC
	curSpeed = getCurSpeed();//车速    
	curReady = getCarReady();//发动机状态
	curBrake = getCarFootBrake();//脚刹
	curHandBrake = getCarHandBrake();//手刹
	N_P = getGearsNOrP();//档位
	
	
	if (tagEngS.saveAccSta != curEngineSta)
	{
		tagEngS.saveAccSta = curEngineSta;
	}
	


	//写在最上面，只要是还没检测到按键，或者按键返回，必须start线 = 0V
	if (tagEngS.StartEngSta == 0x00)
	{
		EngineStart_PowerOff();
	}
	
	#if def_OffDlySec
	switch (offDectecSta)
	{
		case 0x00:
			if (curEngineSta == 0)
			{
				offDectecSta ++;
			}
			break;
		
		case 0x01:
			offDlyCntOld = get1sCounter();
			offDlyCnt = 0;
			offDectecSta ++;
			break;
		
		case 0x02:
			if (get1sCounter() != offDlyCntOld)
			{
				offDlyCntOld = get1sCounter();
				offDlyCnt++;
			}
			
			if (curEngineSta != 0)
			{
				offDectecSta = 0;
				offDlyCnt = 0;
			}
			break;
		
	}
	#endif

	//当前为熄火状态，【后台下发的断电命令】，无反应
	if ((curRelaySta == 0x00) &&	//后台让继电器断电 
		(curEngineSta == 0x00))	//当前为熄火状态
	{
		if((relayPowerOff_hw_sta() != SET) ||
			(EngineStart_PowerOff_sta() != RESET))
		{
			relayPowerOff_hw();
			EngineStart_PowerOff();
		}
		return;
	}
	
	//当前为点火状态，【后台下发的断电命令】，这时和按键无关，只要检测到车速=0，则马上熄火
	if ((curRelaySta == 0x00) &&	//后台让继电器断电 
		(curReady != 0x01) &&	//not ready 
		(curSpeed == 0x0000))	//当前车速=0
	{
		relayPowerOff_hw();
		EngineStart_PowerOff();
		return;
	}
	

	switch (tagEngS.StartEngSta)
	{
		case 0x00:
			if ((curEngineSta == 0x00) &&	//ACC灭
				#if def_OffDlySec
				(offDlyCnt >= 3) &&
				#endif
				(tagEngS.keySta == 0x01) &&	//检测到按键
				(curBrake == 0x01))	//检测到了刹车
			{
				//点火启动
				relayPowerOn_hw();
				#if def_EngineStart_H530
				tagEngS.StartEngSta = 0x07;
				EngineStart_PowerOff();
				#else
				tagEngS.StartEngSta = 0x01;
				EngineStart_PowerOn();
				#endif
				tagEngS.StartEngMsOld = get1msCounter();
			}
			else if ((curEngineSta == 0x00) &&	//ACC灭
				#if def_OffDlySec
				(offDlyCnt >= 3) &&
				#endif
				(tagEngS.keySta == 0x01) &&	//检测到按键
				(curBrake == 0x00))	//没有踩刹车
			{
				//只进入ACC，不启动
				relayPowerOn_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x05;
			}
			else if ((curEngineSta == 0x01) &&	//ACC启动
				(tagEngS.keySta == 0x01) &&	//检测到按键
				(curReady == 0x00) &&	//当前为非Ready状态
				(curBrake == 0x01))	//有踩刹车
			{
				#if (!def_Er30ACCPowoff)  // 特殊要求
				//启动
				//EngineACC_ON_PowerOn();
				#if def_EngineStart_H530
				relayPowerOff_hw();
				tagEngS.StartEngSta = 0x03;
				EngineStart_PowerOff();
				#else
				relayPowerOn_hw();
				tagEngS.StartEngSta = 0x01;
				EngineStart_PowerOn();
				#endif
				tagEngS.StartEngMsOld = get1msCounter();
				#else
				//熄火
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x02;				
				#endif
			}
			else if ((curEngineSta == 0x01) &&	//ACC启动
				(tagEngS.keySta == 0x01) &&	//检测到按键
				(curReady == 0x01) &&	//当前为Ready状态
				#if (!def_EngineStartOffWithoutFootbrake)
				(curBrake == 0x01) &&	//有踩刹车
				#endif
				#if def_EngineOffMustNOrP
				(N_P == 0x01) &&	//要求档位=N或P
				#endif
				(curSpeed == 0x0000) 	//熄火前要求速度=0
				)
			{
				//熄火
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x02;
			}
			else if ((curEngineSta == 0x01) &&	//ACC启动
				(tagEngS.keySta == 0x01) &&	//检测到按键
				(curReady == 0x00) &&	//当前为非Ready状态
				(curSpeed == 0x0000) &&	//熄火前要求速度=0
				#if def_EngineOffMustNOrP
				(N_P == 0x01) &&	//要求档位=N或P
				#endif
				(curBrake == 0x00))	//没踩刹车
			{
				//熄火
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x02;
			}
			//下面是后台要求点火和熄火的流程
			else if (	(curReady == 0x01) &&	//当前为Ready状态
				(ServerEngineCtrl == 0x01) ) 		//点火状态，后台仍然要去点火
			{
				//直接返回成功
				tagEngS.ErrorCode = 0xffff;
				
				
			}
			//新增当前为ON时收到点火命令，则进去启动
//			else if ((curEngineSta == 0x01) &&	//当前ACC ON
//				(ServerEngineCtrl == 0x21))
			else if (ServerEngineCtrl == 0x01)	//无论当前为off还是ON状态，都执行start命令
			{
				//点火启动
				relayPowerOn_hw();
				
				tagEngS.StartEngSta = 0x25;
				EngineStart_PowerOff();
				tagEngS.StartEngMsOld = get1msCounter();
			}
			
			//后台要求熄火,无论ACC或Ready状态
			else if (	(ServerEngineCtrl == 0x02) &&	//后台要求熄火
				#if def_EngineOffMustNOrP
				(N_P == 0x01) &&	//要求档位=N或P
				#endif
				(curSpeed == 0x0000) 	//熄火前要求速度=0
				)
			{
				//熄火
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x20;
			}
			else if ((curEngineSta == 0x00) &&	//当前ACC灭则可以启动，熄火后无法判断N档
				(ServerEngineCtrl == 0x02))				//熄火状态后台仍然要求熄火
			{
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x20;
			}
			else if (ServerEngineCtrl == 0x02)
			{	//后台要求熄火，但是上一步没有执行成功，说明那里条件不满足
				if (N_P != 0x01)
				{
					tagEngS.ErrorCode |= 0x01;
				}
				
				if (curSpeed != 0x0000)
				{
					tagEngS.ErrorCode |= 0x02;
				}
				
			}
			else
			{
				EngineStart_PowerOff();
			}
			break;
		
		case 0x01:
			//等待用户抬起按键
			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(5000))	//点火按了特别长时间，需要强制不按
			{
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 2;
			}
			else if(tagEngS.keySta == 0x00)
			{
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0;
			}
			break;
		
		case 0x02:
			//等待客户松手
			if (tagEngS.keySta == 0x00)
			{
				tagEngS.StartEngSta = 0x00;
			}
			break;
		
		case 0x03:
			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(500))	//
			{
				//启动
				relayPowerOn_hw();
				tagEngS.StartEngMsOld = get1msCounter();
				tagEngS.StartEngSta = 0x04;
			}
			break;
		
		case 0x04:
				tagEngS.StartEngSta = 0x07;
			break;
		
		case 0x05:
			if (curBrake == 0x01)
			{
				//启动
				relayPowerOn_hw();
				#if def_EngineStart_H530
				tagEngS.StartEngSta = 0x07;
				#else
				tagEngS.StartEngSta = 0x01;
				EngineStart_PowerOn();
				#endif
				tagEngS.StartEngMsOld = get1msCounter();
			}
			else if (tagEngS.keySta == 0x00)
			{
				tagEngS.StartEngSta = 0x00;
			}
			
			break;
		
		case 0x06:
			break;
		
		case 0x07:
			#if def_EngineStart_H530
			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(def_EngineOnDly))
			{
				EngineStart_PowerOn();
				tagEngS.StartEngSta = 8;
				tagEngS.StartEngMsOld = get1msCounter();
			}
			#endif
			break;
		
		case 0x08:

			tagEngS.StartEngMsNew = get1msCounter();
			
			if ((getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(2000)) ||
					(Rotate_speed > 1000))	//点火按了特别长时间
			{
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x10;
				tagEngS.StartEngMsOld = get1msCounter();
			}
			else if (curReady == 0x01)	//代表已经进入Ready状态
			{
				//这时再延长0.7秒
				tagEngS.StartEngSta = 0x09;
				tagEngS.StartEngMsOld = get1msCounter();
			}

			break;
			
		case 0x09:
			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(700))
			{
				tagEngS.StartEngSta = 0x10;
				EngineStart_PowerOff();
			}
			break;
		
		case 0x10:
			EngineStart_PowerOff();
			tagEngS.StartEngSta = 2;
			break;
		
		case 0x11:
			break;
		
		case 0x12:
			break;
		
		case 0x20:
			tagEngS.StartEngSta = 0;
			tagEngS.ErrorCode	= 0xffff;//OK
		
			break;
		
		
		case 0x25:
			tagEngS.StartEngMsNew = get1msCounter();
			if (((curHandBrake == 0x01)||(curBrake == 0x01)) && 
				(N_P == 0x01))
			{
				tagEngS.StartEngSta = 0x27;
			}
			else if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(5000))
			{
				//超过5秒CAN 数据无法检测手刹，支持熄火
				relayPowerOff_hw();
				EngineStart_PowerOff();
				tagEngS.StartEngSta = 0x00;
				
				if (curHandBrake != 0x01)
				{
						tagEngS.ErrorCode	|= 0x04;	//手刹没检测到
				}
				
				if (curBrake != 0x01)
				{
					tagEngS.ErrorCode	|= 0x08;	//手刹没检测到
				}
				
				if (N_P != 0x01)
				{
					tagEngS.ErrorCode |= 0x01;
				}
			}
			break;
			
		case 0x27:

			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(500))
			{
				EngineStart_PowerOn();
				tagEngS.StartEngSta = 0x28;
				tagEngS.StartEngMsOld = get1msCounter();
			}

			break;
			
		case 0x28:

			tagEngS.StartEngMsNew = get1msCounter();
			if ((getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(2000)) ||
					(Rotate_speed > 1000))	//点火按了特别长时间
				{
					EngineStart_PowerOff();
					tagEngS.StartEngSta = 0x30;
					tagEngS.StartEngMsOld = get1msCounter();
				}
				else if (curReady == 0x01)	//代表已经进入Ready状态
				{
					//这时再延长0.7秒
					tagEngS.StartEngSta = 0x29;
					tagEngS.StartEngMsOld = get1msCounter();
				}

			break;
				
		case 0x29:

			tagEngS.StartEngMsNew = get1msCounter();
			if (getTim1MsElaps(tagEngS.StartEngMsNew, tagEngS.StartEngMsOld) > _MS(700))
			{
				tagEngS.StartEngSta = 0x30;
				EngineStart_PowerOff();
			}

			break;		
				
				
		case 0x30:
			//理论上点火成功
			EngineStart_PowerOff();
			tagEngS.StartEngSta = 0;
			tagEngS.ErrorCode = 0xffff;		
//			if (curReady != 0x01)
//			{
//				tagEngS.ErrorCode |= 0x10;
//			}

			break;
			
		
		default:
			break;

	}
}





/*
tagEngS.keySta = 0x00; 按键抬起
0x01:按下
*/
void detect_engine_start_keyPress(void)
{
	
	switch(tagEngS.keySta)
	{
		case 0x00:
			//检测按键按下
			if ((tagEngS.keyStep == 0x00) &&
				(engine_key_rd() == 0x01))
			{
				tagEngS.keyStep++;
				tagEngS.keyMsOld = get1msCounter();
			}
			else if (tagEngS.keyStep == 0x01)
			{
				//按键防抖
				tagEngS.keyMsNew = get1msCounter();
				if (getTim1MsElaps(tagEngS.keyMsNew, tagEngS.keyMsOld) > 20)
				{
					if (engine_key_rd() == 0x01)
					{
						tagEngS.keyStep++;
					}
					else
					{
						tagEngS.keyStep = 0;
					}
				}
			}
			else if (tagEngS.keyStep == 0x02)
			{
				tagEngS.keySta = 0x01;	//表示检测到了按键
				tagEngS.keyStep = 0x00;
				tagEngS.keyMsOld = get1msCounter();
			}
			else
			{
				tagEngS.keyStep = 0x00;
			}
		
			break;
		
		case 0x01:
			//判断按键抬起
			if (tagEngS.keyStep == 0x00)
			{
				tagEngS.keyMsNew = get1msCounter();
				if (getTim1MsElaps(tagEngS.keyMsNew, tagEngS.keyMsOld) > _MS(800))
				{
					tagEngS.keyStep++;
				}
			}
			else if ((tagEngS.keyStep == 0x01) &&
				(engine_key_rd() == 0x00))
			{
				tagEngS.keyStep++;
				tagEngS.keyMsOld = get1msCounter();
			}
			else if (tagEngS.keyStep == 0x02)
			{
				//按键防抖
				tagEngS.keyMsNew = get1msCounter();
				if (getTim1MsElaps(tagEngS.keyMsNew, tagEngS.keyMsOld) > 20)
				{
					if (engine_key_rd() == 0x00)
					{
						tagEngS.keyStep++;
					}
					else
					{
						tagEngS.keyStep = 0;
					}
				}
			}
			else if (tagEngS.keyStep == 0x03)
			{
				tagEngS.keySta = 0x00;	//表示检测到了松开按键
				tagEngS.keyStep = 0x00;
			}
			else
			{
				tagEngS.keyStep = 0x00;
			}
			break;
	}
}
	

/*
返回1，进入ready
返回0，未知，或未进入ready
*/
uint8_t getCarReady(void)
{
	if ((0x02 & u8AutoIgSt()) == 0x02)
	{
		return 1;
	}
	
	return 0;
}

/*
返回1，进入N huo P
返回0，未知，或未进
*/
uint8_t getGearsNOrP(void)
{
	if ((0x04 & u8AutoGearSt()) == 0x04)
	{
		return 1;
	}
	else if ((0x10 & u8AutoGearSt()) == 0x10)
	{
		return 1;
	}
	
	return 0;
}

/*
返回1，检测到脚刹
返回0，未知，或未检测到脚刹
*/
uint8_t getCarFootBrake(void)
{
	if ((0x02 & u8AutoGearSt()) == 0x02)
	{
		return 1;
	}
	
	return 0;
}

uint8_t getCarHandBrake(void)
{
	if ((0x01 & u8AutoGearSt()) == 0x01)
	{
		return 1;
	}
	
	return 0;
}
//通电返回1，断电返回0
uint8_t getRelayCurSta(void)
{
	if (getCurrentRelayCtrlSta() == 1)
	{
		return 1;
	}
	return 0;
}
/*
点火返回1，熄火返回0
*/
uint8_t getCurEngine(void)
{
	if ((0x08 & u8AutoIgSt()) == 0x08)
	{
		return 1;
	}
	return 0;
}
/*
车速
*/
uint16_t getCurSpeed(void)
{
	uint16_t reDa;
	
	reDa = u16AutoSpeed();
	
	return ( reDa );
}

#endif	

